![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Liyad (Lisp yet another DSL interpreter) is very small Lisp interpreter written in JavaScript.
Liyad (Lisp yet another DSL interpreter, or LIYAD is yum and delicious) is
very small Lisp interpreter written in JavaScript.
You can easily start making your new DSL using Lisp and S-expression.
from NPM:
$ npm install liyad --save
or download from release page.
See liyad-cli .
$ npm install -g liyad-cli
$ liyad
https://shellyln.github.io/liyad/playground.html
LSX is an alternative JSX notation using Lisp.
No transpiler needed
Secure execution for untrusted contents
Simple and powerful
The LSX runtime directly calls React.createElement
(or a JSX Factory function such as
RedAgate,
Vue.js, etc.) as a Lisp function,
Convert a Lisp list to a renderer component object tree.
In order to resolve the renderer component, you must register the object's constructor with the LSX runtime in advance.
All unresolved lisp function symbols are dispatched to React.createElement('some_unresolved_name', ...)
.
You can declare HTML/XML standard tags.
As with JSX, LSX must always return a single component.
Using Template
Lisp function instead of JSX Fragment
tag will produce the same result.
lsx`
(Template
(select (@ (style (display "inline-block")
(width "300px") )
(className "foo bar baz")
(onChange ${(e) => this.handleExampleSelected(e.target.value)}) )
($=for ${exampleCodes}
($=if (== (% $index 2) 1)
(option (@ (value $index)) ($concat "odd: " ($get $data "name")) )
)
($=if (== (% $index 2) 0)
(option (@ (value $index)) ($concat "even: " ($get $data "name")) )
)
)
)
)`;
Playground's source code is written in LSX.
import { S } from 'liyad';
console.log(
JSON.stringify(S`
($list
1 2 3 "a" "b" "C"
($list 4 5 6) ${"X"} ${["Y", "Z"]}
)`
// You can also parse by calling w/o template literal syntax as following:
// S(' ... ')
)
);
Output:
[{"symbol":"$list"},1,2,3,"a","b","C",[{"symbol":"$list"},4,5,6],{"value":"X"},{"value":["Y","Z"]}]
import { lisp } from 'liyad';
console.log(
JSON.stringify(lisp`
($defun fac (n)
($if (== n 0)
1
(* n ($self (- n 1))) ))
($list
1 2 (fac 3) "a" "b" "c"
($list 4 5 (fac 6) ${"X"} ${["Y", "Z"]})
)`
// You can also evaluate by calling w/o template literal syntax as following:
// lisp(' ... ')
)
);
Output:
[1,2,6,"a","b","c",[4,5,720,"X",["Y","Z"]]]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { LSX } from 'liyad';
var lsx = null;
const exampleCodes = [{
name: "Example1: factorial",
code: ` ... `
}, {
name: "Example2: Hello, World!",
code: ` ... `,
}];
class ExampleLoader extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {};
}
handleExampleSelected(i) {
this.props.loadExample(i);
}
render() {
return (lsx`
(Template
(select (@ (style (display "inline-block")
(width "300px") )
(onChange ${(e) => this.handleExampleSelected(e.target.value)}) )
($=for ${exampleCodes}
(option (@ (value $index)) ($get $data "name") )
)
)
)`);
}
}
class App extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {};
}
loadExample(i) {
console.log(exampleCodes[i].code);
}
render() {
return (lsx`
(Template
(div (@ (style (margin "4px")))
(ExampleLoader (@ (loadExample ${(i) => this.loadExample(i)}) ))
)
)`);
}
}
var lsx = LSX({
jsx: React.createElement,
jsxFlagment: React.Fragment,
components: {
ExampleLoader,
App,
},
});
ReactDOM.render(lsx`(App)`, document.getElementById('app'));
import { SxFuncInfo,
SxMacroInfo,
SxSymbolInfo,
SExpression,
SxParserConfig,
defaultConfig,
installCore,
installArithmetic,
installSequence } from 'liyad';
const myOperators: SxFuncInfo[] = [{
name: '$__defun',
fn: (state: SxParserState, name: string) => (...args: any[]) => {
// S expression: ($__defun 'name '(sym1 ... symN) 'expr ... 'expr)
// -> S expr : fn
const car: SxSymbol = $$first(...args);
if (args.length < 3) {
throw new Error(`[SX] $__defun: Invalid argument length: expected: ${3} / args: ${args.length}.`);
}
const fn = $__lambda(state, name)(...args.slice(1));
state.funcMap.set(car.symbol, {
name: car.symbol,
fn: (st, nm) => fn
});
return fn;
},
}];
const myMacros: SxMacroInfo[] = [{
name: '$defun',
fn: (state: SxParserState, name: string) => (list) => {
// S expression: ($defun name (sym1 ... symN) expr ... expr)
// -> S expr : ($__defun 'name '(sym1 ... symN) 'expr ... 'expr)
return [{symbol: '$__defun'},
...(list.slice(1).map(x => quote(state, x))),
];
},
}];
const mySymbols: SxSymbolInfo[] = [
{name: '#t', fn: (state: SxParserState, name: string) => true}
];
export const MyDSL = (() => {
let config: SxParserConfig = Object.assign({}, defaultConfig);
config = installCore(config);
config = installArithmetic(config);
config = installSequence(config);
config.stripComments = true;
config.funcs = (config.funcs || []).concat(myOperators);
config.macros = (config.macros || []).concat(myMacros);
config.symbols = (config.symbols || []).concat(mySymbols);
return SExpression(config);
})();
console.log(
JSON.stringify(MyDSL`( ... )`)
);
"""
Hello, Liyad!
"""
is equivalent to:
(Template
"
Hello, Liyad!
"
)
"""
Hello, %%%($get name)!
"""
is equivalent to:
(Template
"
Hello, " ($get name) "!
"
)
"""div
Hello, %%%($get name)!
"""
is equivalent to:
(div
"
Hello, " ($get name) "!
"
)
"""div@{(id "123") (class "foo bar baz")}
Hello, %%%($get name)!
"""
is equivalent to:
(div (@ (id "123") (class "foo bar baz"))
"
Hello, " ($get name) "!
"
)
($list 1 2 ...($concat (3 4) (5 6)) 7 8)
is equivalent to:
($list 1 2 ($spread ($concat (3 4) (5 6))) 7 8)
and is to be:
[1,2,3,4,5,6,7,8]
$spread
is NOT a macro. The list passed as a parameter is spliced after evaluation.
($list 1 2 3 4 ($splice (5 6 7 8)) 9 10)
is equivalent to:
($list 1 2 3 4 5 6 7 8 9 10)
(($splice ($call x add)) 5 7)
is equivalent to:
($call x add 5 7)
(::foo:bar:baz= 7)
is equivalent to:
($set ("foo" "bar" "baz") 7)
($list ::foo:bar:baz)
is equivalent to:
($list ($get "foo" "bar" "baz"))
(::foo:bar@baz 3 5 7)
is equivalent to:
($call ($get "foo" "bar") baz 3 5 7)
($defun f (x ...y)
($list x y) )
($list
(f 1)
(f 1 2)
(f 1 2 3)
(f 1 2 3 4)
(f 1 2 3 4 5) )
is to be:
[
[1,[]],
[1,[2]],
[1,[2,3]],
[1,[2,3,4]],
[1,[2,3,4,5]]
]
Verbatim string literal
($last @"c:\documents\files\u0066.txt")
is to be:
"c:\\documents\\files\\u0066.txt"
Normal string literal
($last "c:\documents\files\u0066.txt")
is to be:
"c:documents\filesf.txt"
SExpression
Create a new DSL.
interface SxParserConfig {
raiseOnUnresolvedSymbol: boolean;
enableEvaluate: boolean;
enableHereDoc: boolean;
enableSpread: boolean;
enableSplice: boolean;
enableShorthands: boolean;
enableVerbatimStringLiteral: boolean;
enableTailCallOptimization: boolean;
stripComments: boolean;
wrapExternalValue: boolean;
reservedNames: SxReservedNames;
returnMultipleRoot: boolean;
maxEvalCount: number;
jsx?: (comp: any, props: any, ...children: any[]) => any;
JsxFragment?: any;
funcs: SxFuncInfo[];
macros: SxMacroInfo[];
symbols: SxSymbolInfo[];
funcSymbolResolverFallback?: SxFunc;
valueSymbolResolverFallback?: SxSymbolResolver;
}
function SExpression(config: SxParserConfig): (strings: TemplateStringsArray | string, ...values?: any[]) => SxToken
config
: Parser config.S
Parse a S-expression.
function S(strings: TemplateStringsArray | string, ...values?: any[]): SxToken
strings
: Template strings.values
: values.lisp
Evaluate a Lisp code.
function lisp(strings: TemplateStringsArray | string, ...values?: any[]): SxToken
strings
: Template strings.values
: values.lisp_async
Evaluate a Lisp code.
(asynchronous features are enabled.)
function lisp_async(strings: TemplateStringsArray | string, ...values?: any[]): Promise<SxToken>
strings
: Template strings.values
: values.LM
Evaluate a Lisp code (returns multiple value).
function LM(strings: TemplateStringsArray | string, ...values?: any[]): SxToken
strings
: Template strings.values
: values.LM_async
Evaluate a Lisp code (returns multiple value).
(asynchronous features are enabled.)
function LM_async(strings: TemplateStringsArray | string, ...values?: any[]): Promise<SxToken>
strings
: Template strings.values
: values.LSX
Evaluate a Lisp code as LSX.
interface LsxConfig {
jsx: (comp: any, props: any, ...children: any[]) => any;
jsxFlagment: any;
components: object;
}
function LSX<R = SxToken>(lsxConf: LsxConfig): (strings: TemplateStringsArray, ...values: any[]) => R
lsxConf
: LSX config.LSX_async
Evaluate a Lisp code as LSX.
(asynchronous features are enabled.)
interface LsxConfig {
jsx: (comp: any, props: any, ...children: any[]) => any;
jsxFlagment: any;
components: object;
}
function LSX_async<R = SxToken>(lsxConf: LsxConfig): (strings: TemplateStringsArray, ...values: any[]) => Promise<R>
lsxConf
: LSX config.runScriptTags
Run script tags.
function runScriptTags(
lisp: SExpressionTemplateFn | SExpressionAsyncTemplateFn,
globals?: object,
contentType = 'text/lisp')
lisp
: Evaluater function.globals
: Global variables.contentType
: Content type attribute of script tags.Usage:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script type="text/lisp">
($local ((body (::document@querySelector "body")))
($set (body innerText) "Hello, Lisp! ") )
($local (c) ($capture (c)
($$defun tarai(x y z)
($set c (+ c 1))
($if (<= x y)
y
($self ($self (- x 1) y z)
($self (- y 1) z x)
($self (- z 1) x y))))
($list ($datetime-to-iso-string ($now)) (tarai 13 6 0) c) ))
</script>
<script src="liyad.min.js"></script>
<script>
// Since the above lisp code refers to the body element,
// you need to enclose the lisp evaluation with addEventListener.
document.addEventListener('DOMContentLoaded', function(event) {
const result = JSON.stringify(
liyad.runScriptTags(liyad.lisp, {window, document}));
const body = document.querySelector('body');
setTimeout(() => body.innerText = body.innerText + result, 30);
});
</script>
</head>
<body></body>
See core, arithmetic, sequence, concurrent, JSX (LSX) operators.
ISC
Copyright (c) 2018, Shellyl_N and Authors.
FAQs
Liyad (Lisp yet another DSL interpreter) is very small Lisp interpreter written in JavaScript.
The npm package liyad receives a total of 3,577 weekly downloads. As such, liyad popularity was classified as popular.
We found that liyad demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.